# coding=utf-8

import sys
import os
from tool import *
import subprocess
from datetime import datetime
import shutil
import time
from oss import *
import requests

begin_time = datetime.now()
print("---------- python run begin ----------")
print(begin_time)
print("---------- python run . ----------")
if os.path.exists("requirements.txt"):
    call_command("pip3 install -r requirements.txt")

# call_command("git lfs install")
# call_command("cd ..")
# call_command("git pull")
# call_command("git submodule update")
# call_command("cd BuildTool")

from dotenv import load_dotenv

BASE_DIR = os.path.abspath(os.path.dirname(__file__))

# pip3 freeze > requirements.txt
# pip3 install -r requirements.txt
# pip install python-dotenv dotenv

local_ip = log_device()

call_command("git branch")
commitid = adb_shell("git rev-parse --short HEAD") or ""
print("Git commitid ", commitid)

print("---------- environ ----------")
load_dotenv(os.path.join(BASE_DIR, '.env'))
print(os.environ)
print("---------- environ ----------\n")

macos_unity_path = os.environ.get("MACOS_UNITY_PATH")
windows_unity_path = os.environ.get("WINDOWS_UNITY_PATH")
root_path = os.path.abspath(os.path.join(os.getcwd(), "../"))
project_path = root_path
BuildNote = os.environ.get("BuildNote", "")
project_type = os.environ.get("ProjectType")

BuildTargetInt = os.environ.get("BuildTarget")
AB_BuildTarget = os.environ.get("AB_BuildTarget", "1")
_BuildTarget = {
    "2": "Android",
    "3": "iOS",
    "1": "Pico",
    "4": "Win",
    "5": "MaxOSX"
}

BuildTarget = _BuildTarget.get(AB_BuildTarget)
IsDelCache = os.environ.get('IsDelCache', 'false').lower() in ['true', 'on', '1']
IsOutputConsole = os.environ.get('IsOutputConsole', 'true').lower() in ['true', 'on', '1']
IsUploadOSS = os.environ.get('IsUploadOSS', 'true').lower() in ['true', 'on', '1']
product_name = os.environ.get('ProductName').replace(" ", "_")
Version = os.environ.get("Version")

print("---------- last config ----------")
last_resconfig_dict = get_last_version(project_type, BuildTarget, Version)
print("res_version_dict >>> ")
print(last_resconfig_dict)
print("\n********** \n")
if last_resconfig_dict:
    _AB_ResVersion = last_resconfig_dict.get("ResVersion")

print("---------- last config ----------\n")

AB_ResVersion = os.environ.get("AB_ResVersion", "-1")
if AB_ResVersion == "-1":
    if not last_resconfig_dict:
        AB_ResVersion = "1"
    else:
        _AB_ResVersion = int(_AB_ResVersion) + 1
        AB_ResVersion = str(_AB_ResVersion)
build_ab_dir = os.path.join(root_path, "AssetBundles", "Build" + project_type, BuildTarget)
if IsDelCache:
    rmDirAllFiles(build_ab_dir)

build_version_path = os.path.join(build_ab_dir, Version)

timestr = begin_time.strftime("%Y_%m_%d_%H_%M_%S")

log_dir = os.path.join(root_path, "AssetBundles", "logs")
create_dir(log_dir)
delExtFiles(log_dir, "*.log")

print("Start Build ", timestr)
print("project_path ", project_path)
print("build_version_path ", build_version_path)

ABConfig_name = "ResConfig.json"


def IsUpdateAB():
    if not last_resconfig_dict:
        return True, "需要更新,无远端"
    if os.environ.get("AB_ResVersion", "-1") != "-1":
        return True, "需要更新，指定版本"
    remote_items = last_resconfig_dict['Bundles']

    abconfig_path = os.path.join(build_version_path, AB_ResVersion, ABConfig_name)
    result = read_file(abconfig_path)
    if not result:
        return False, "打包AB错误,没有本地版本"
    config_dict = json.loads(result)
    local_items = config_dict['Bundles']

    print("remote_items", remote_items)
    print("local_items", local_items)

    def find_index(items, item):
        for i in range(len(items)):
            _item = items[i]
            if _item['BundleName'] == item['BundleName']:
                # 对比
                # if _item['MD5'] != item['MD5']:
                #     return -1
                # if _item['Size'] != item['Size']:
                #     return -1
                # if _item['Scenes'] != item['Scenes']:
                #     return -1
                return i
        return -1

    for item in local_items:
        i = find_index(remote_items, item)
        if i == -1:
            print("local", item)
            print("")
            return True, "需要更新，新增bundle"
        _item = remote_items[i]
        if _item['md5'] != item['md5']:
            print("\n当前本地 需要更新 MD5不一致")
            print("remote ", _item)
            print("local", item)
            print("")
            return True, "需要更新，MD5不一致"
        del remote_items[i]
    return False, "无更新，本地和远端完全一致"


def uploadab_oss():
    if not IsUploadOSS:
        print("upload_oss IsUploadOSS=false 不上传oss")
        return
    local_path = os.path.join(build_version_path, AB_ResVersion)
    oss_path = os.path.join("oss://faramita/vr-ota/AssetBundle/MetaNew",
                            project_type, BuildTarget, Version, AB_ResVersion)
    r1 = upload_oss(local_path, oss_path)

    local_path = os.path.join(build_version_path, AB_ResVersion, ABConfig_name)
    oss_path = os.path.join("oss://faramita/vr-ota/AssetBundle/MetaNew",
                            project_type, BuildTarget, Version, ABConfig_name)
    r2 = upload_oss(local_path, oss_path)
    info = "\nUoload OSS : {}".format(r1)
    info += "\nUpload OSS Config: {}".format(r2)
    return info


def upload_local_it_share():
    local_path = os.path.join(build_version_path, AB_ResVersion)
    try:
        target_dir = os.path.join("/Volumes/samba/Jenkins", product_name,
                                  project_type + "_" + BuildTarget + "_New_AB_" + begin_time.strftime("%Y%m%d"),
                                  timestr + "_" + Version + "_" + AB_ResVersion, BuildTarget)
        result = "\nIT共享目录: BuildDir:{}".format(local_path) + \
                 "\nIT共享目录: TargetDir:{}".format(target_dir)
        print(result)
        # delExtFiles(target_dir, "*.*", True)
        create_dir(target_dir)
        copyDir(local_path, target_dir)
        url = target_dir.replace("/Volumes", "file://172.16.100.240")
        result += "\nIT共享目录:\n\n{}\n\n 账号/密码: genimous ".format(url)
        print("IT共享目录:\n{}\n 账号/密码: genimous ".format(url))
        return result
    except Exception as e:
        result = "IT共享目录: 上传失败 {} ".format(local_path)
        result += "\nIT共享目录: Error: {}".format(str(e))
        print(result)
        return result


def sendFeishu(arg_list):
    JOB_URL = os.environ.get("BUILD_URL", "")
    print("JOB_URL", JOB_URL)
    JOB_URL = JOB_URL.replace("0.0.0.0", local_ip).replace("127.0.0.1", local_ip)
    JOB_NAME = os.environ.get("JOB_NAME", "")
    BUILD_NUMBER = str(os.environ.get("BUILD_NUMBER", 0))
    url = "https://open.feishu.cn/open-apis/bot/v2/hook/fb8b127b-6169-4fb4-a988-5116156a199c"
    method = 'post'
    headers = {
        'Content-Type': 'application/json'
    }
    arg = "------------------------------\n"
    arg += BuildNote
    for i in arg_list:
        if i:
            arg += "\n" + str(i)
    arg += "\n------------------------------"
    end_time = datetime.now()
    use_time = end_time - begin_time
    use_time = str(use_time)
    json = {
        "msg_type": "interactive",
        "card": {
            "config": {
                "wide_screen_mode": True,
                "enable_forward": True
            },
            "elements": [{
                "tag": "div",
                "text": {
                    "content": "项目名称：" + JOB_NAME + \
                               "\n构建编号：第" + BUILD_NUMBER + "次构建" + \
                               "\n开始时间：" + begin_time.strftime("%Y-%m-%d %H:%M:%S") + \
                               "\n结束时间：" + end_time.strftime("%Y-%m-%d %H:%M:%S") + \
                               "\n总耗时：" + use_time + \
                               "\nGit Commit ID：" + commitid + \
                               "\n Jenkins Url:" + JOB_URL + "\n " + arg,
                    "tag": "lark_md"
                }
            }, {
                "actions": [{
                    "tag": "button",
                    "text": {
                        "content": "查看报告",
                        "tag": "lark_md"
                    },
                    "url": JOB_URL,
                    "type": "default",
                    "value": {}
                }],
                "tag": "action"
            }],
            "header": {
                "title": {
                    "content": JOB_NAME + " 构建报告",
                    "tag": "plain_text"
                }
            }
        }
    }
    requests.request(method=method, url=url, headers=headers, json=json)


# https://docs.unity3d.com/cn/2019.4/Manual/CommandLineArguments.html
# https://docs.unity3d.com/Manual/EditorCommandLineArguments.html
def callUnity(script_and_method, args_dict: dict):
    print("\n---------- Begin Build----------")
    print("Begin CallUnity,", script_and_method, args_dict, "\n")
    log_file = os.path.join(log_dir, script_and_method + "_" + timestr + ".log")
    rmFile(log_file)
    print("please see log ", log_file)

    args_str = ""
    for key, value in args_dict.items():
        if value is None or value == "":
            args_str += " -" + key
        else:
            args_str += " -{}=\"{}\"".format(key, value)
    #     + " -noUpm" \

    if sys.platform == "win32":
        command = windows_unity_path \
                  + " -batchmode" \
                  + " -quit" \
                  + " -logFile " + log_file \
                  + " -projectPath " + project_path \
                  + " -executeMethod " + script_and_method \
                  + args_str
    if sys.platform == "darwin":
        command = macos_unity_path \
                  + " -batchmode" \
                  + " -quit" \
                  + " -logFile " + log_file \
                  + " -projectPath " + project_path \
                  + " -executeMethod " + script_and_method \
                  + args_str

    if IsOutputConsole:
        tail_file(log_file)

    print("callUnity", command)
    a = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    a.wait()
    print(datetime.now(), a.poll())
    time.sleep(10)

    print("---------- Build End ---------- ")
    print("End CallUnity,please see log ", log_file, "\n")
    print("打包AB执行时间", datetime.now() - begin_time)

    result_list = []
    r, msg = IsUpdateAB()
    print("IsUpload ", r, msg)
    
    result_list.append("\n对比OSS是否更新: " + str(r))
    result_list.append("MSG:" + msg)
    if r:
        rlist = uploadab_oss()
        result_list.append(rlist)
    r = upload_local_it_share()
    result_list.append(r)

    print("Upload Done!")
    result_list.append("\n"+project_path)
    result_list.append("\n"+script_and_method)
    result_list.append("\n"+args_str)
    sendFeishu(result_list)


# https://docs.unity3d.com/cn/2019.4/Manual/CommandLineArguments.html
# buildTarget Standalone、Win、Win64、OSXUniversal、Linux64、iOS、Android、WebGL、XboxOne、PS4、WindowsStoreApps、Switch、tvOS
args_dict = {
    "Version": Version,
    "AB_ResVersion": AB_ResVersion,
    "AB_BuildTarget": AB_BuildTarget,
    "timeStr": timestr,
    "gitCommitId": commitid,
}
print("callUnity args ")
print(args_dict)
print("")
callUnity("CommandBuild.BuildAB", args_dict)

end_time = datetime.now()
print("总执行时间", end_time - begin_time)
